package cn.js.sangu.unitStore.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;

import cn.hutool.core.util.StrUtil;
import cn.js.sangu.unitStore.common.LogType;
import cn.js.sangu.unitStore.common.MyAuthAccess;
import cn.js.sangu.unitStore.common.MyLogsAOP;
import cn.js.sangu.unitStore.common.R;
import cn.js.sangu.unitStore.common.exception.ServiceException;
import cn.js.sangu.unitStore.dto.PartAttributeDTO;
import cn.js.sangu.unitStore.entity.User;
import cn.js.sangu.unitStore.entity.BomEntity;
import cn.js.sangu.unitStore.service.BomService;
import cn.js.sangu.unitStore.service.UserService;
import lombok.extern.slf4j.Slf4j;

/**
 * 说明：Bom清单接口
 * 作者：linshuo
 * 日期：2025/9/9 12:54
 */
@Slf4j
@RequestMapping("bom")
@RestController
public class BomController {

    static final String OPERATION_UTILS = "Bom清单";

    @Autowired
    BomService bomService;

    @Autowired
    UserService userService;

    @MyLogsAOP(operation = OPERATION_UTILS, operaType = LogType.LOOKUP)
    @GetMapping("findByPage")
    public R findByPage(@RequestParam Integer pageNum,
            @RequestParam Integer pageSize,
            @RequestParam String workName,
            @RequestParam String creator,
            @RequestParam String attachName) {
        QueryWrapper<BomEntity> wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(workName), "work_name", workName);
        wrapper.like(StrUtil.isNotBlank(creator), "creator", creator);
        wrapper.like(StrUtil.isNotBlank(attachName), "attach_name", attachName);
        wrapper.orderByDesc("id");

        // 构建page对象
        Page<BomEntity> param = new Page<>(pageNum, pageSize);

        Page<BomEntity> res = null;
        try {
            res = bomService.page(param, wrapper);
        } catch (DataAccessException e) {
            throw new ServiceException("SQL语法出现错误");
        } catch (Exception e) {
            throw new ServiceException("系统接口出现错误，请联系管理员，错误码:500");
        }
        return R.ok(res.setRecords(suppleName(res.getRecords())));
    }

    @MyLogsAOP(operation = OPERATION_UTILS, operaType = LogType.ADD)
    @RequestMapping("save")
    public R save(@RequestBody BomEntity dto) throws JsonProcessingException {
        // 这里可能需要将 BomEntity 转换为 BomEntity
        BomEntity distribute = bomService.saveInfo(dto);
        return R.ok("《" + distribute.getWorkName() + "》记录保存成功，可查看处理状态");
    }

    @MyLogsAOP(operation = OPERATION_UTILS, operaType = LogType.UPDATE)
    @PutMapping("update")
    public R update(@RequestBody BomEntity dto) {
        // 这里可能需要将 BomEntity 转换为 BomEntity
        bomService.updateInfo(dto);
        return R.ok("修改成功");
    }

    @MyLogsAOP(operation = OPERATION_UTILS, operaType = LogType.DELETE)
    @DeleteMapping("delete/{id}")
    public R delete(@PathVariable Integer id) {
        bomService.removeById(id);
        return R.ok("删除成功");
    }

    @MyLogsAOP(operation = OPERATION_UTILS, operaType = LogType.BATCH_DELETE)
    @DeleteMapping("deleteBatch")
    public R deleteBatch(@RequestBody List<Integer> ids) {
        bomService.removeBatchByIds(ids);
        return R.ok("批量删除成功");
    }

    // @MyLogsAOP(operation = OPERATION_distributeUMENT,operaType = LogType.LOOKUP)
    @MyAuthAccess
    @GetMapping("findById/{id}")
    public R findById(@PathVariable Integer id) {
        BomEntity distribute = bomService.getById(id);
        User user = userService.getById(distribute.getCreator());
        if (null != user) {
            distribute.setCreatorName(user.getName());
        }
        return R.ok(distribute);
    }

    // @MyLogsAOP(operation = OPERATION_distributeUMENT,operaType = LogType.LOOKUP)
    @GetMapping("findByRecent")
    public R findByRecent() {
        LambdaQueryWrapper<BomEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.orderByDesc(BomEntity::getCreatTime).last("LIMIT 10");
        return R.ok(suppleName(bomService.list(wrapper)));
    }

    /**
     * 补充创建人+修改人+接收人 名称
     * 
     * @param list
     * @return
     */
    private List<BomEntity> suppleName(List<BomEntity> list) {
        for (BomEntity distribute : list) {
            // 创建人
            User author = userService.getById(distribute.getCreator());
            if (null != author)
                distribute.setCreatorName(author.getName());
            // 修改人
            User modifier = userService.getById(distribute.getModifier());
            if (null != modifier)
                distribute.setModifierName(modifier.getName());
            // 接收人
            User recipient = userService.getById(distribute.getRecipient());
            if (null != recipient)
                distribute.setRecipientName(recipient.getName());
        }
        return list;
    }

    /**
     * 下载文件
     * 
     * @param response
     */
    @MyLogsAOP(operation = OPERATION_UTILS, operaType = LogType.DOWNLOAD_FILE)
    @GetMapping("/download")
    public void download(@RequestParam String id,
            @RequestParam(required = false, defaultValue = "attachment") String type,
            HttpServletResponse response) {
        try {
            if (id == null) {
                throw new ServiceException("请提供文件对应的ID");
            }
            BomEntity entity = bomService.getById(id);
            if (entity == null) {
                throw new ServiceException("目标文件不存在");
            }
            if (entity.getState() != 2) {
                throw new ServiceException("加工状态异常，请核对");
            }

            String targetPath = entity.getAttachType();
            File file = new File(targetPath);

            if (!file.exists() || !file.isFile()) {
                throw new ServiceException("文件不存在或不是有效的文件");
            }

            try (FileInputStream fileInputStream = new FileInputStream(file);
                    OutputStream outputStream = response.getOutputStream()) {

                // 动态设置 Content-Type
                String contentType = getContentType(file.getName());
                response.setCharacterEncoding("utf-8");
                response.setContentType(contentType);

                if ("attachment".equals(type)) {
                    String fileName = URLEncoder.encode(file.getName(), "UTF-8");
                    response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);
                    response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                } else if ("preview".equals(type)) {
                    // 确保预览模式也设置 Content-Disposition
                    String fileName = URLEncoder.encode(file.getName(), "UTF-8");
                    response.setHeader("Content-Disposition", "inline; filename*=UTF-8''" + fileName);
                    response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                }
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
        } catch (ServiceException e) {
            log.error("文件下载业务异常: {}", e.getMessage());
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            try {
                response.getWriter().write(e.getMessage());
            } catch (IOException ioException) {
                log.error("响应异常信息失败", ioException);
            }
        } catch (IOException e) {
            log.error("文件下载IO异常", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                response.getWriter().write("文件下载失败，请联系管理员");
            } catch (IOException ioException) {
                log.error("响应异常信息失败", ioException);
            }
        }
    }

    /**
     * 根据文件名获取 Content-Type
     * 
     * @param fileName 文件名
     * @return Content-Type
     */
    private String getContentType(String fileName) {
        if (fileName.endsWith(".pdf")) {
            return "application/pdf";
        } else if (fileName.endsWith(".docx")) {
            return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        } else if (fileName.endsWith(".xlsx")) {
            return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        } else {
            return "application/octet-stream";
        }
    }

    @MyAuthAccess
    @GetMapping(value = "test", produces = "text/plain;charset=UTF-8")
    public String test(HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        return bomService.test();
    }

    @MyAuthAccess
    @GetMapping("testws/{uid}")
    public R testWs(@PathVariable String uid) {
        bomService.testWs(uid);
        return R.ok("测试请求OK");
    }

}
